package result

import (
	"errors"
	"log"
	"property_service/internal/svc"
	"property_service/mqs"
	"property_service/mqs/message"
	"property_service/property_service"
	"property_service/utils/iface"
	"strings"

	"gorm.io/gorm"
)

var (
	ErrDuplicateEntry       = errors.New("'名称' 或 '编码' 或 '其他' 值已经存在")
	ErrRecordNotFound       = errors.New("record not found")
	ErrInvalidSQL           = errors.New("invalid SQL")
	ErrInvalidTransaction   = errors.New("invalid transaction")
	ErrCantStartTransaction = errors.New("can't start transaction")
	ErrUnaddressable        = errors.New("unaddressable error")
	ErrDBConnection         = errors.New("database connection error")
)

type Result struct {
	message string
	err     error
	code    int32
}

func Err(err error) iface.IErr {
	return &Result{
		"",
		err,
		1,
	}
}

func AsyncMsg(ctx *svc.ServiceContext, messageKey interface{}, userId int64) {
	msg, msgErr := message.ToMsg(message.AsyncComm, messageKey, userId)
	if msgErr != nil {
		log.Printf("Error creating message text: %v", msgErr)
	}
	mqs.Push(ctx, msg)
}

func Suc() iface.ISuc {
	return &Result{
		code: 0,
	}
}

func (r *Result) AddEd(mes ...string) (*property_service.Response, error) {
	if mes == nil || len(mes) != 1 {
		mes = []string{"添加成功"}
	}
	return &property_service.Response{
		Message: mes[0],
		Code:    r.code,
	}, nil
}

func (r *Result) EditEd(mes ...string) (*property_service.Response, error) {
	if mes == nil || len(mes) != 1 {
		//if value.RowsAffected != 0 {
		//	mes = []string{"修改成功"}
		//}
		mes = []string{"修改成功"}
	}
	return &property_service.Response{
		Message: mes[0],
		Code:    r.code,
	}, nil
}

func (r *Result) DelEd(mes ...string) (*property_service.Response, error) {
	if mes == nil || len(mes) != 1 {
		mes = []string{"删除成功"}
	}
	return &property_service.Response{
		Message: mes[0],
		Code:    r.code,
	}, nil
}

func (r *Result) ExeEd(mes string) (*property_service.Response, error) {
	return &property_service.Response{
		Message: mes,
		Code:    r.code,
	}, nil
}

func (r *Result) Ed(val ...string) (*property_service.Response, error) {
	err := handleGormErr(r.err, val...)
	result := &property_service.Response{
		Code:    r.code,
		Message: err.Error(),
	}
	if r.code != 0 {
		return result, err
	}
	return result, nil
}

func handleGormErr(err error, val ...string) error {
	switch {
	case errors.Is(err, gorm.ErrRecordNotFound):
		return joinErr(ErrRecordNotFound, val...)
	default:
		if strings.Contains(err.Error(), "1062") {
			return joinErr(ErrDuplicateEntry, val...)
		} else if strings.Contains(err.Error(), "1146") {
			return joinErr(ErrUnaddressable, val...)
		} else if strings.Contains(err.Error(), "1054") {
			return joinErr(ErrUnaddressable, val...)
		}
	}
	return err
}

func joinErr(err error, str ...string) error {
	for _, sub := range str {
		err = errors.Join(err, errors.New(sub))
	}
	return err
}
